"""
LangChainGraph 主应用
FastAPI应用入口点
"""

import warnings
import asyncio
from typing import AsyncGenerator
from contextlib import asynccontextmanager
from fastapi import FastAPI
from fastapi.openapi.docs import (
    get_redoc_html,
    get_swagger_ui_html,
    get_swagger_ui_oauth2_redirect_html,
)
from fastapi.middleware.cors import CORSMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.responses import Response
from fastapi.requests import Request
from fastapi.responses import JSONResponse

# 忽略pkg_resources弃用警告，因为这是jieba库内部使用导致的
warnings.filterwarnings("ignore", category=UserWarning, module="jieba")
# 忽略websockets弃用警告，这是由uvicorn依赖的第三方库产生的警告
warnings.filterwarnings("ignore", category=DeprecationWarning, module="websockets.server")

# 设置日志
from src.utils.logging import setup_logging, get_logger
setup_logging()
logger = get_logger(__name__)

# 数据库和配置初始化
from src.config import settings
from src.config.database import init_db, check_db_health

# 服务导入
from src.services.monitoring_service import monitoring_service
from src.services.tracing_service import tracing_service
from src.services.service_registry import service_registry

# 中间件
from src.middleware.error_handler import setup_global_error_handling
from src.middleware.security_headers import setup_security_middleware

# 依赖注入容器
from src.containers import init_container

# 主动服务管理器
from src.services.proactive_service_manager import ProactiveServiceManager

# MCP相关导入和初始化
MCP_AVAILABLE = False
FastApiMCP = None
patch_fastapi_mcp_recursion = None
MCPPluginLoader = None

try:
    from fastapi_mcp import FastApiMCP
    # 应用MCP递归问题修复补丁
    from src.utils.mcp_fix import patch_fastapi_mcp_recursion
    from src.utils.mcp_plugin_loader import MCPPluginLoader
    MCP_AVAILABLE = True
except ImportError:
    MCP_AVAILABLE = False

# 导入所有路由（在设置日志和数据库之后导入，避免循环导入问题）
from src.routes.tickets import router as tickets_router
from src.routes.auth import router as auth_router
from src.routes.groups import router as groups_router
from src.routes.database_metadata import router as database_router
from src.routes.generic_query import router as query_router
from src.routes.research import router as research_router
from src.routes.knowledge_base import router as knowledge_base_router
from src.routes.scheduler import router as scheduler_router
from src.routes.feishu import router as feishu_router
from src.routes.sessions import router as sessions_router
from src.routes.mcp import router as mcp_router
from src.routes.voice_call import router as voice_call_router
from src.routes.websocket import router as websocket_router
from src.routes.service_gateway import router as service_gateway_router
from src.routes.health import router as health_router
from src.routes.knowledge_graph import router as knowledge_graph_router
from src.routes.chatbot import router as chatbot_router
from src.routes.projects import router as projects_router
from src.routes.user_preferences import router as user_preferences_router
from src.routes.query_cache import router as query_cache_router
from src.routes.security_demo import router as security_demo_router
from src.routes.federated_learning import router as federated_learning_router
from src.routes.proactive import router as proactive_router


# Lifespan事件处理器
@asynccontextmanager
async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]:
    """应用生命周期事件处理器"""
    logger.info("🚀 LangChainGraph 启动中...")
    
    # 初始化数据库
    try:
        init_db()
        logger.info("✅ 数据库初始化完成")
    except Exception as e:
        logger.error(f"❌ 数据库初始化失败: {e}")
    
    # 检查数据库连接
    if check_db_health():
        logger.info("✅ 数据库连接正常")
    else:
        logger.error("❌ 数据库连接失败")
    
    # 初始化依赖注入容器
    init_container()
    
    # 注册所有服务
    try:
        service_registry.register_learning_services()
        # 注册服务包装器中的服务
        from src.services.service_wrappers import register_all_services
        register_all_services()
        logger.info("✅ 服务注册完成")
    except Exception as e:
        logger.error(f"❌ 服务注册失败: {e}")
    
    # 初始化种子数据
    try:
        from src.config import seed_data
        seed_data.init_seed_data()
        logger.info("种子数据初始化完成")
    except Exception as e:
        logger.error(f"种子数据初始化失败: {e}")
    
    # 启动主动服务
    try:
        proactive_manager = ProactiveServiceManager()
        await proactive_manager.start_services()
        logger.info("✅ 主动服务已启动")
    except Exception as e:
        logger.error(f"❌ 启动主动服务失败: {e}")
    
    logger.info(f"🌐 服务将在 {settings.HOST}:{settings.PORT} 启动")
    logger.info(f"📚 API文档: http://{settings.HOST}:{settings.PORT}/docs")
    
    yield
    
    # 关闭阶段
    logger.info("🛑 LangChainGraph 正在关闭...")
    
    # 停止主动服务
    try:
        proactive_manager = ProactiveServiceManager()
        await proactive_manager.stop_services()
        logger.info("✅ 主动服务已停止")
    except Exception as e:
        logger.error(f"❌ 停止主动服务失败: {e}")

def create_app():
    """创建FastAPI应用"""
    app = FastAPI(
        title="智能研发平台",
        description="基于LangChain和知识图谱的智能研发平台",
        version="1.0.0",
        docs_url=None,  # 禁用默认的/docs路径
        redoc_url=None,  # 禁用默认的/redoc路径
        lifespan=lifespan
    )
    
    # 初始化追踪服务
    tracing_service.setup_tracing("LangChainGraph")
    tracing_service.instrument_fastapi(app)
    tracing_service.instrument_requests()

    # 设置监控仪器
    monitoring_service.setup_instrumentation(app)   
    
    # 设置安全中间件
    setup_security_middleware(app)
    # 配置跨域资源共享
    app.add_middleware(
        CORSMiddleware,
        allow_origins=getattr(settings, 'CORS_ORIGINS', ["*"]),
        allow_credentials=True,
        allow_methods=["*"],
        allow_headers=["*"],
        expose_headers=["*"]
    )
    
    # 设置全局异常处理
    setup_global_error_handling(app)
    
    # 挂载静态文件
    app.mount("/static", StaticFiles(directory="static"), name="static")
    
    # 注册路由
    app.include_router(auth_router, prefix="/api")
    app.include_router(tickets_router, prefix="/api")
    app.include_router(groups_router, prefix="/api")
    app.include_router(database_router, prefix="/api")
    app.include_router(query_router, prefix="/api")
    app.include_router(research_router, prefix="/api")
    app.include_router(scheduler_router, prefix="/api")
    app.include_router(feishu_router, prefix="/api")
    app.include_router(sessions_router, prefix="/api")
    app.include_router(mcp_router, prefix="/api")
    app.include_router(health_router, prefix="/api")
    app.include_router(knowledge_graph_router, prefix="/api")
    app.include_router(websocket_router, prefix="")
    app.include_router(security_demo_router, prefix="/api")
    app.include_router(query_cache_router, prefix="/api")
    app.include_router(service_gateway_router, prefix="/api")
    app.include_router(voice_call_router, prefix="/api")
    app.include_router(projects_router, prefix="/api")
    app.include_router(federated_learning_router, prefix="/api")
    app.include_router(knowledge_base_router, prefix="/api")
    app.include_router(chatbot_router, prefix="/api")
    app.include_router(user_preferences_router, prefix="/api")    
    app.include_router(proactive_router, prefix="/api")
    
    # 加载MCP插件
    if MCP_AVAILABLE and FastApiMCP and MCPPluginLoader:
        try:
            # 先检查并增加递归限制
            import sys
            current_limit = sys.getrecursionlimit()
            if current_limit < 2000:
                sys.setrecursionlimit(2000)
                logger.info(f"已将递归限制从 {current_limit} 增加到 2000")
            
            mcp = FastApiMCP(app)
            mcp.mount_http()
            logger.info("FastAPI-MCP 初始化成功")
            
            # 加载MCP插件
            plugin_loader = MCPPluginLoader()
            plugin_loader.load_all_plugins()
            logger.info("MCP插件加载完成")
        except RecursionError as re:
            logger.error(f"MCP初始化递归错误: {re}")
            logger.error("可能是FastAPI-MCP与应用生命周期事件处理冲突，请检查依赖关系")
        except Exception as e:
            logger.error(f"MCP初始化失败: {e}")
    else:
        logger.warning("MCP支持不可用，请安装fastapi_mcp包以启用MCP功能")   
        
    
    return app

# 创建应用实例
app = create_app()

# Prometheus指标端点
@app.get("/metrics")
async def metrics():
    """Prometheus指标端点"""
    from prometheus_client import generate_latest, CONTENT_TYPE_LATEST
    return Response(generate_latest(), media_type=CONTENT_TYPE_LATEST)

# 自定义Swagger UI路由
@app.get("/docs", include_in_schema=False)
async def custom_swagger_ui_html():
    if app.openapi_url:
        return get_swagger_ui_html(
            openapi_url=app.openapi_url,
            title=app.title + " - Swagger UI",
            oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
            swagger_js_url="/static/libs/swagger-ui-bundle.js",
            swagger_css_url="/static/libs/swagger-ui.css",
        )

@app.get(app.swagger_ui_oauth2_redirect_url or "/swagger/oauth2-redirect", include_in_schema=False)
async def swagger_ui_redirect():
    return get_swagger_ui_oauth2_redirect_html()

# 自定义ReDoc路由
@app.get("/redoc", include_in_schema=False)
async def redoc_html():
    if app.openapi_url:
        return get_redoc_html(
            openapi_url=app.openapi_url,
            title=app.title + " - ReDoc",
            redoc_js_url="/static/libs/redoc.standalone.js",
        )

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(
        "src.main:app",
        host=getattr(settings, 'HOST', '127.0.0.1'),
        port=getattr(settings, 'PORT', 8000),
        reload=getattr(settings, 'DEBUG', False),
        log_level="info"
    )
